﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;

namespace theguineasyndrome
{
    public class WaterWeapon : Weapon
    {
        private Texture2D[] dropTextures;
        private Texture2D[] flakeTextures;

        private SoundEffect primarySound;
        private int lastTimePrimaryPlayed;

        private List<WaterDrop> drops;
        private Random random;

        public WaterWeapon(Texture2D[] flakeTextures, Texture2D[] dropTextures, SoundEffect primarySound)
        {
            this.flakeTextures = flakeTextures;
            this.dropTextures = dropTextures;
            this.primarySound = primarySound;
            lastTimePrimaryPlayed = 0;
            drops = new List<WaterDrop>();
            random = new Random();
        }

        public override Vector2 firePrimary(int time, Vector2 position, Vector2 speed)
        {
            if (lastTimePrimaryPlayed < time - 300)
            {
                primarySound.Play();
                lastTimePrimaryPlayed = time;
            }

            speed *= 17;
            speed.X += ((float)random.NextDouble() - 0.5f) * 1.5f;
            speed.Y += ((float)random.NextDouble() - 0.5f) * 1.5f;

            drops.Add(new WaterDrop(level, getRandomFlakeTexture(), position, speed, WaterDrop.LIFE_TIME - (float)random.NextDouble() / 2, time));

            Vector2 acceleration = new Vector2(-speed.X, -speed.Y);
            acceleration.Normalize();
            return acceleration * 0.17f;
        }

        public override Vector2 fireSecondary(int time, Vector2 position, Vector2 speed)
        {
            primarySound.Play();
            int numDrops = random.Next(20, 30);

            for (int i = 0; i < numDrops; i++)
            {
                Vector2 dropSpeed = new Vector2(((float)random.NextDouble() - 0.5f) * 3, 20 + ((float)random.NextDouble() - 0.5f) * 40);
                drops.Add(new WaterDrop(level, getRandomFlakeTexture(), position, dropSpeed, WaterDrop.LIFE_TIME - (float)random.NextDouble() / 2, time));
            }

            return new Vector2(0, -20);
        }

        public override float getPrimaryPeriod()
        {
            return 10;
        }

        public override float getSecondaryPeriod()
        {
            return 2000;
        }

        private Texture2D getRandomFlakeTexture()
        {
            return flakeTextures[random.Next(flakeTextures.Length)];
        }

        private Texture2D getRandomDropTexture()
        {
            return dropTextures[random.Next(dropTextures.Length)];
        }

        public override void Update(GameTime gameTime)
        {
            int time = (int)gameTime.TotalGameTime.TotalMilliseconds;
            List<WaterDrop> newDrops = new List<WaterDrop>();

            for (int i = drops.Count - 1; i >= 0; i--)
            {
                LiquidDrop drop = drops[i];
                drop.Update(gameTime);
                if (drop.isDead())
                {
                    ObstacleElement killingObstacle = drop.getKillingObstacle();
                    if (killingObstacle != null)
                        killingObstacle.removeSplashesAt(drop.X - drop.getRadius() / 2, drop.X + drop.getRadius() / 2);

                    float lifeTime = drop.getLifeTime() - 0.5f - (float)random.NextDouble() / 2;
                    if (lifeTime > 0)
                    {
                        Vector2 speed = drop.NextDropSpeed;

                        int numDrops = random.Next(2, 5);
                        for (int j = 0; j < numDrops; j++)
                        {
                            speed.X = speed.X + (float)(random.NextDouble() - 0.5) * lifeTime * 7;
                            speed.Y = speed.Y + (float)(random.NextDouble() - 0.5) * lifeTime * 7;
                            speed *= 0.6f;
                            newDrops.Add(new WaterDrop(level, getRandomDropTexture(), drop.Position, speed, lifeTime, time));
                        }
                    }
                    drops.RemoveAt(i);
                }
                else if (drop.Top > level.Bottom)
                    drops.RemoveAt(i);
            }

            foreach (WaterDrop newDrop in newDrops)
                drops.Add(newDrop);
        }

        public override void queueDrawing(Camera camera)
        {
            foreach (WaterDrop drop in drops)
                drop.queueDrawing(camera);
        }


        public override bool primaryRequiresJustClicked()
        {
            return false;
        }

        public override bool secondaryRequiresJustClicked()
        {
            return false;
        }

        public override void clear()
        {
            drops.Clear();
        }
    }
}
